package jobs

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"alipayDmp/alipay"
	"alipayDmp/mysql"
	"github.com/google/uuid"
)

const (
	inputFile = "/data/device/logs/qps/bd-lh-alipay-push.txt"
	//inputFile    = "/Users/suntao/Project/alipayDmp/bd-lh-alipay-push.txt"
	bufferSize   = 1024 * 1024 // 64KB buffer size
	linesPerFile = 4000
)

func BaiDuJob() {

	//crowds := CrowdMap{}
	crowds := getCrowdData()

	deviceChan := make(chan []string, 10)

	go readFile(deviceChan)

	fileCount := 1
	count := uint8(0)
	aUuid := strings.ReplaceAll(uuid.New().String(), "-", "")

	crowd := crowds[count]

	for deviceIds := range deviceChan {
		time.Sleep(150 * time.Millisecond)
		ifEnd := fileCount%5000 == 0
		if len(deviceIds) != linesPerFile {
			ifEnd = true
		}

		go sendALiPay(deviceIds, count, ifEnd, aUuid, crowd)

		if ifEnd {
			count++
			aUuid = strings.ReplaceAll(uuid.New().String(), "-", "")
			crowd = crowds[count]
		}
		fileCount++
	}

	log.Println("完成")
}

func sendALiPay(deviceIds []string, count uint8, ifEnd bool, uuid string, crowd Crowd) {

	crowdPrefix := "BaiDuDmp-%d"
	crowdName := fmt.Sprintf(crowdPrefix, count)
	var crowdId string

	oType := "ADD"
	if crowd.Id > 0 {
		oType = "UPDATE_ALL"
		crowdId = crowd.CrowdId
		crowdName = crowd.CrowdName
	}
	//log.Println("ot-", oType, '-', len(deviceIds))
	//return

	log.Println(oType, ",cId:", crowdId, ",cName", crowdName, "len:", len(deviceIds))

	err, res := alipay.Send(crowdName, oType, deviceIds, ifEnd, uuid, crowdId)
	if err != nil {
		log.Println("结果:上传失败", err.Error())
		return
	}
	if ifEnd && res.CrowdId != "" {
		log.Printf("CrowdId:%s,CrowdName:%s \n", res.CrowdId, res.CrowdName)
	}
	if ifEnd && oType == "ADD" {
		c := Crowd{
			CrowdId:   res.CrowdId,
			CrowdName: crowdName,
			Seq:       count,
		}
		mysql.DB.Save(&c)
	}
}

func readFile(r chan []string) {
	log.Println("读取文件开始")
	// 打开输入文件
	file, err := os.Open(inputFile)
	if err != nil {
		log.Println("打开文件失败：", err.Error())
		return
	}
	defer file.Close()

	deviceIds := make([]string, 0)

	// 使用带缓冲的读取器
	reader := bufio.NewReaderSize(file, bufferSize)
	for {
		// 读取一行
		line, err := reader.ReadString('\n')
		if err != nil {
			// 判断是否到达文件结尾
			if err.Error() == "EOF" {
				r <- deviceIds
				close(r)
				break
			}
		}
		line = strings.ReplaceAll(line, "\n", "")
		deviceIds = append(deviceIds, line)

		// 如果达到行数
		if len(deviceIds) >= linesPerFile {
			r <- deviceIds
			deviceIds = []string{}
		}
	}
}

type Crowd struct {
	Id        int    `gorm:"primary_key" json:"id,omitempty"`
	CrowdId   string `json:"crowd_id,omitempty"`
	Seq       uint8  `json:"seq,omitempty"`
	CrowdName string `json:"crowd_name,omitempty"`
}

func (c Crowd) TableName() string {
	return "alipay_crowds"
}

type CrowdMap map[uint8]Crowd

func getCrowdData() CrowdMap {
	c := Crowd{}
	var data []Crowd
	mysql.DB.Model(&c).Order("seq asc").Find(&data)
	cRes := CrowdMap{}
	for _, item := range data {
		cRes[item.Seq] = item
	}
	return cRes
}
